from functools import partial

from requests import Request
from rest_framework import authentication
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import BasePermission
from rest_framework.views import APIView

from User.Auth import TokenAuth, TokenAuthResult
from User.models import SiteUser
from misaka.modelViewSet.withUserModelViewSet import ManagerOwnerViewSet


# ----------------- Authentication 认证类
class isLogin(BaseAuthentication):
    """
    是否登录
    筛选出登录的用户
    """

    def authenticate(self, request: Request):
        auth_header = request.headers.get('Authorization')
        if not auth_header:
            return [None, None]
        tokenAuthResult: TokenAuthResult = TokenAuth.valid_user_token(auth_header)
        if tokenAuthResult.Flag:
            uid = tokenAuthResult.User
            user = SiteUser.objects.get(id=uid)
            return [user, None]
        else:
            return [None, None]


# ----------------- Permission 权限类
class hasUser(BasePermission):
    def has_permission(self, request, view):
        if request.user:
            return request.user.id


class isAdminUser(BasePermission):
    def has_permission(self, request, view):
        user: SiteUser | None = request.user
        if user is not None:
            return user.is_superuser
        return False


class ManagerOwner(BasePermission):
    """
    遵守契约设计，使用本权限需要视图继承超类 `ManagerOwnerSetView`
    只能管理自己资源的权限
    """

    class ManagerOwnerException(Exception):
        ...

    def has_permission(self, request, view):
        if request.user is None:
            return False

        return request.user.id is not None

    def has_object_permission(self, request, view: ManagerOwnerViewSet, obj):
        try:
            method = view.get_obj_user
        except Exception:
            raise self.ManagerOwnerException("ManagerOwner权限类需要视图是ManagerOwnerViewSet子类~")
        return method(obj).id == request.user.id
